﻿using Ndns.ServerHost.Abstractions;
using Ndns.ServerHost.Middlewares;
using System;
using System.Threading.Tasks;

namespace Ndns.ServerHost.Builder
{
    public static class BranchingMiddlewareBuilderExtensions
    {

        public static IDnsServerHostBuilder RunWhen(this IDnsServerHostBuilder builder, Func<DnsContext, bool> condition, Action<IMiddlewaresBuilder> builderDelegate)
        {
            if (builder == null)
                throw new ArgumentNullException();

            builder.ConfigureMiddlewares((mbuilder) =>
            {
                mbuilder.Use(new BranchingMiddleware((c) =>
                {
                    return new ValueTask<bool>(condition(c));
                }, builderDelegate, false));
            });

            return builder;
        }

        public static IDnsServerHostBuilder RunWhen(this IDnsServerHostBuilder builder, Func<DnsContext, Task<bool>> condition, Action<IMiddlewaresBuilder> builderDelegate)
        {
            if (builder == null)
                throw new ArgumentNullException();

            builder.ConfigureMiddlewares((mbuilder) =>
            {
                mbuilder.Use(new BranchingMiddleware((c) =>
                {
                    return new ValueTask<bool>(condition(c));
                }, builderDelegate, false));
            });

            return builder;
        }

        public static IDnsServerHostBuilder RunWhen(this IDnsServerHostBuilder builder, Func<DnsContext, ValueTask<bool>> condition, Action<IMiddlewaresBuilder> builderDelegate)
        {
            if (builder == null)
                throw new ArgumentNullException();

            builder.ConfigureMiddlewares((mbuilder) =>
            {
                mbuilder.Use(new BranchingMiddleware(condition, builderDelegate, false));
            });

            return builder;
        }

        public static IDnsServerHostBuilder UseWhen(this IDnsServerHostBuilder builder, Func<DnsContext, bool> condition, Action<IMiddlewaresBuilder> builderDelegate)
        {
            if (builder == null)
                throw new ArgumentNullException();

            builder.ConfigureMiddlewares((mbuilder) =>
            {
                mbuilder.Use(new BranchingMiddleware((c) =>
                {
                    return new ValueTask<bool>(condition(c));
                }, builderDelegate, true));
            });

            return builder;
        }

        public static IDnsServerHostBuilder UseWhen(this IDnsServerHostBuilder builder, Func<DnsContext, Task<bool>> condition, Action<IMiddlewaresBuilder> builderDelegate)
        {
            if (builder == null)
                throw new ArgumentNullException();

            builder.ConfigureMiddlewares((mbuilder) =>
            {
                mbuilder.Use(new BranchingMiddleware((c) =>
                {
                    return new ValueTask<bool>(condition(c));
                }, builderDelegate, true));
            });

            return builder;
        }

        public static IDnsServerHostBuilder UseWhen(this IDnsServerHostBuilder builder, Func<DnsContext, ValueTask<bool>> condition, Action<IMiddlewaresBuilder> builderDelegate)
        {
            if (builder == null)
                throw new ArgumentNullException();

            builder.ConfigureMiddlewares((mbuilder) =>
            {
                mbuilder.Use(new BranchingMiddleware(condition, builderDelegate, true));
            });

            return builder;
        }
    }
}
